package controllers

import (
	"AcServer/src/configration"
	"AcServer/src/models"
	"AcServer/src/utils"
	"encoding/json"
	"github.com/beego/beego/v2/client/orm"
	"github.com/beego/beego/v2/server/web"
	"io"
	"os"
	"strconv"
)

type GetJobController struct {
	web.Controller
}

type AddJobController struct {
	web.Controller
}

type UpdateJobController struct {
	web.Controller
}

type HeartBeatController struct {
	web.Controller
}

type GetHeartBeatController struct {
	web.Controller
}

type AddVersionController struct {
	web.Controller
}

type EditVersionController struct {
	web.Controller
}

type GetVersionController struct {
	web.Controller
}

type AddVersionFileController struct {
	web.Controller
}

type UploadFileController struct {
	web.Controller
}

type DeleteVersionController struct {
	web.Controller
}

type AddDeviceController struct {
	web.Controller
}

type DeviceGetListController struct {
	web.Controller
}

type PostJobBody struct {
	Id        int    `json:"id"`
	JobName   string `json:"job_name"`
	Status    int    `json:"status"`
	Type      int    `json:"type"`
	ExtraInfo string `json:"extra_info"`
}

type PostGetJobBody struct {
	Status  int `json:"status"`   //1:new 2:post 3:finish
	JobType int `json:"job_type"` //1:up 2:down
}

type PostVersionBody struct {
	Id            int    `orm:"pk"`
	VersionName   string `json:"versionName"`
	VersionCode   string `json:"versionCode"`
	UpdateContent string `json:"updateContent"`
	DownloadUrl   string `json:"downloadUrl"`
	ExtraInfo     string `json:"extraInfo"`
	CreateTime    string `json:"createTime"`
	UpdateTIme    string `json:"updateTime"`
}

type PostGetDeviceBody struct {
	DeviceNo       string `json:"deviceNo"`
	DeviceModel    string `json:"deviceModel"`
	DeviceBrand    string `json:"deviceBrand"`
	AndroidVersion string `json:"AndroidVersion"`
	AppVersion     string `json:"appVersion"`
	IsRunning      bool   `json:"isRunning"`
	IsInputting    bool   `json:"isInputting"`
	StartTime      string `json:"startTime"`
	EndTime        string `json:"endTime"`
	Page           int    `json:"page"`
	Limit          int    `json:"limit"`
}

func (this *GetJobController) Post() {
	var getJobBody PostGetJobBody
	resMap := make(map[string]interface{})
	resMap["result"] = 0
	request := this.Ctx.Input.RequestBody

	err := json.Unmarshal(request, &getJobBody)
	if err != nil {
		resMap["extraMsg"] = &err
		this.Data["json"] = &resMap
		this.ServeJSON()
		return
	}

	var jobList []models.Job
	o := orm.NewOrm()
	whereSql := " WHERE 1=1 "
	if getJobBody.JobType == 1 {
		whereSql += " AND type=1 "
	} else if getJobBody.JobType == 2 {
		whereSql += " AND type=2 "
	}
	if getJobBody.Status == 1 {
		whereSql += " AND status=1 ORDER BY job_time DESC LIMIT 1"
	} else if getJobBody.Status == 2 {
		whereSql += " AND status=2 "
	} else if getJobBody.Status == 3 {
		whereSql += " AND status=3 "
	}

	sql := "SELECT * FROM job " + whereSql
	num, err := o.Raw(sql).QueryRows(&jobList)
	if err != nil {
		resMap["extraMsg"] = "read failed"
		this.Data["json"] = &resMap
		this.ServeJSON()
		return
	}
	if num == 0 {
		resMap["extraMsg"] = "no data"
		resMap["result"] = 1
		this.Data["json"] = &resMap
		this.ServeJSON()
		return
	}

	var job = jobList[0]
	job.Status = 2
	o.Update(&job)

	resMap["result"] = 1
	resMap["data_list"] = &jobList
	this.Data["json"] = &resMap
	this.ServeJSON()
}

func (this *AddJobController) Post() {

	var postBody PostJobBody

	resMap := make(map[string]interface{})
	resMap["result"] = 0
	request := this.Ctx.Input.RequestBody

	err := json.Unmarshal(request, &postBody)
	if err != nil {
		resMap["extraMsg"] = &err
		this.Data["json"] = &resMap
		this.ServeJSON()
		return
	}

	var job models.Job
	job.JobName = postBody.JobName
	job.JobTime = utils.GetCurrentTime()
	job.ExtraInfo = postBody.ExtraInfo
	job.Status = 1
	job.Type = postBody.Type

	o := orm.NewOrm()
	_, err = o.Insert(&job)
	if err != nil {
		resMap["extraMsg"] = "insert job " + job.JobName + " error"
	} else {
		resMap["result"] = 1
	}

	this.Data["json"] = &resMap
	this.ServeJSON()
}

func (this *UpdateJobController) Post() {

	var postBody PostJobBody

	resMap := make(map[string]interface{})
	resMap["result"] = 0

	request := this.Ctx.Input.RequestBody

	err := json.Unmarshal(request, &postBody)
	if err != nil {
		resMap["extraMsg"] = &err
		this.Data["json"] = &resMap
		this.ServeJSON()
		return
	}

	var job models.Job
	job.Id = postBody.Id
	job.JobName = postBody.JobName
	job.JobTime = utils.GetCurrentTime()
	job.ExtraInfo = postBody.ExtraInfo
	job.Status = postBody.Status
	job.Type = postBody.Type

	o := orm.NewOrm()
	_, err = o.Update(&job)
	if err != nil {
		resMap["extraMsg"] = "update job " + job.JobName + " error"
	} else {
		resMap["result"] = 1
	}

	this.Data["json"] = &resMap
	this.ServeJSON()
}

func (this *HeartBeatController) Post() {

	var postBody models.Heart

	resMap := make(map[string]interface{})
	resMap["result"] = 0
	request := this.Ctx.Input.RequestBody

	err := json.Unmarshal(request, &postBody)
	if err != nil {
		resMap["extraMsg"] = &err
		this.Data["json"] = &resMap
		this.ServeJSON()
		return
	}

	o := orm.NewOrm()
	_, err = o.Insert(&postBody)
	if err != nil {
		resMap["extraMsg"] = "insert heart error"
	} else {
		resMap["result"] = 1
	}

	this.Data["json"] = &resMap
	this.ServeJSON()
}

func (this *GetHeartBeatController) Post() {

	resMap := make(map[string]interface{})
	resMap["result"] = 0

	var heartList []models.Heart
	o := orm.NewOrm()

	sql := "SELECT * FROM heart ORDER BY heart_time DESC LIMIT 10"
	num, err := o.Raw(sql).QueryRows(&heartList)
	if err != nil {
		resMap["extraMsg"] = "read failed"
		this.Data["json"] = &resMap
		this.ServeJSON()
		return
	}

	if num == 0 {
		resMap["extraMsg"] = "no data"
		resMap["result"] = 1
		this.Data["json"] = &resMap
		this.ServeJSON()
		return
	}

	resMap["result"] = 1
	resMap["data_list"] = &heartList
	this.Data["json"] = &resMap
	this.ServeJSON()
}

func (this *AddVersionController) Post() {

	var postBody PostVersionBody

	resMap := make(map[string]interface{})
	resMap["result"] = 0
	request := this.Ctx.Input.RequestBody

	err := json.Unmarshal(request, &postBody)
	if err != nil {
		resMap["extraMsg"] = &err
		this.Data["json"] = &resMap
		this.ServeJSON()
		return
	}

	var version models.Version
	version.VersionName = postBody.VersionName
	version.VersionCode = postBody.VersionCode
	version.DownloadUrl = postBody.DownloadUrl
	version.UpdateContent = postBody.UpdateContent
	version.ExtraInfo = postBody.ExtraInfo
	version.CreateTime = utils.GetCurrentTime()
	version.UpdateTime = utils.GetCurrentTime()

	o := orm.NewOrm()
	_, err = o.Insert(&version)
	if err != nil {
		resMap["extraMsg"] = "insert version " + version.VersionName + " error"
	} else {
		resMap["result"] = 1
	}

	this.Data["json"] = &resMap
	this.ServeJSON()
}

func (this *AddVersionFileController) Post() {

	var postBody PostVersionBody

	resMap := make(map[string]interface{})
	resMap["result"] = 0
	request := this.GetString("requestBody")
	err := json.Unmarshal([]byte(request), &postBody)
	if err != nil {
		resMap["extraMsg"] = "json.Unmarshal error "
		resMap["error"] = &err
		this.Data["json"] = &resMap
		this.ServeJSON()
		return
	}

	// 获取上传的文件
	file, header, fileErr := this.GetFile("file")
	if fileErr != nil {
		resMap["extraMsg"] = "GetFile error "
		resMap["error"] = &err
		this.Data["json"] = &resMap
		this.ServeJSON()
		return
	}
	defer file.Close()

	fileName := header.Filename
	// 创建目标文件
	dst, crerr := os.Create(configration.Global.File.LocalDir + fileName)
	if crerr != nil {
		resMap["extraMsg"] = "Create file error "
		resMap["error"] = &err
		this.Data["json"] = &resMap
		this.ServeJSON()
		return
	}
	defer dst.Close()

	// 将上传的文件内容复制到目标文件
	_, cperr := io.Copy(dst, file)
	if cperr != nil {
		resMap["extraMsg"] = "Copy file error "
		resMap["error"] = &err
		this.Data["json"] = &resMap
		this.ServeJSON()
		return
	}

	var version models.Version
	version.VersionName = postBody.VersionName
	version.VersionCode = postBody.VersionCode
	version.DownloadUrl = configration.Global.File.DownloadHost + "AutoClock/" + fileName
	version.UpdateContent = postBody.UpdateContent
	version.ExtraInfo = postBody.ExtraInfo
	version.CreateTime = utils.GetCurrentTime()
	version.UpdateTime = utils.GetCurrentTime()

	o := orm.NewOrm()
	_, err = o.Insert(&version)
	if err != nil {
		resMap["extraMsg"] = "insert version " + version.VersionName + " error"
		resMap["error"] = &err
	} else {
		resMap["extraMsg"] = "insert version " + version.VersionName + " success"
		resMap["result"] = 1
	}

	this.Data["json"] = &resMap
	this.ServeJSON()
}

func (this *EditVersionController) Post() {

	var postBody PostVersionBody

	resMap := make(map[string]interface{})
	resMap["result"] = 0
	request := this.Ctx.Input.RequestBody

	err := json.Unmarshal(request, &postBody)
	if err != nil {
		resMap["extraMsg"] = &err
		this.Data["json"] = &resMap
		this.ServeJSON()
		return
	}

	var version models.Version
	version.Id = postBody.Id
	version.VersionName = postBody.VersionName
	version.VersionCode = postBody.VersionCode
	version.DownloadUrl = postBody.DownloadUrl
	version.UpdateContent = postBody.UpdateContent
	version.ExtraInfo = postBody.ExtraInfo
	version.UpdateTime = utils.GetCurrentTime()

	o := orm.NewOrm()
	_, err = o.InsertOrUpdate(&version)
	if err != nil {
		resMap["extraMsg"] = "InsertOrUpdate version " + version.VersionName + " error"
	} else {
		resMap["result"] = 1
	}

	this.Data["json"] = &resMap
	this.ServeJSON()
}

func (this *GetVersionController) Post() {

	resMap := make(map[string]interface{})
	resMap["result"] = 0

	var versionList []models.Version
	o := orm.NewOrm()

	sql := "SELECT * FROM version ORDER BY create_time DESC "
	num, err := o.Raw(sql).QueryRows(&versionList)
	if err != nil {
		resMap["extraMsg"] = "read failed"
		this.Data["json"] = &resMap
		this.ServeJSON()
		return
	}

	if num == 0 {
		resMap["extraMsg"] = "no data"
		resMap["result"] = 1
		this.Data["json"] = &resMap
		this.ServeJSON()
		return
	}

	resMap["result"] = 1
	resMap["data_list"] = &versionList
	this.Data["json"] = &resMap
	this.ServeJSON()
}

func (this *UploadFileController) Post() {

	resMap := make(map[string]interface{})
	resMap["result"] = 0

	// 获取上传的文件
	file, header, err := this.GetFile("file")
	if err != nil {
		resMap["extraMsg"] = "get file error "
		resMap["error"] = &err
		this.Data["json"] = &resMap
		this.ServeJSON()
		return
	}
	defer file.Close()

	fileName := header.Filename
	// 创建目标文件
	dst, crerr := os.Create(configration.Global.File.LocalDir + fileName)
	if crerr != nil {
		resMap["extraMsg"] = "create file error "
		resMap["error"] = &crerr
		this.Data["json"] = &resMap
		this.ServeJSON()
		return
	}
	defer dst.Close()

	// 将上传的文件内容复制到目标文件
	_, err = io.Copy(dst, file)
	if err != nil {
		resMap["extraMsg"] = &err
		this.Data["json"] = &resMap
		this.ServeJSON()
		return
	}

	resMap["result"] = 1
	resMap["extraMsg"] = "Upload file success!"
	this.Data["json"] = &resMap
	this.ServeJSON()
}

func (this *DeleteVersionController) Post() {

	var postBody PostVersionBody

	resMap := make(map[string]interface{})
	resMap["result"] = 0
	request := this.Ctx.Input.RequestBody

	err := json.Unmarshal(request, &postBody)
	if err != nil {
		resMap["extraMsg"] = &err
		this.Data["json"] = &resMap
		this.ServeJSON()
		return
	}

	var version models.Version
	version.Id = postBody.Id
	version.VersionName = postBody.VersionName
	version.VersionCode = postBody.VersionCode
	version.DownloadUrl = postBody.DownloadUrl
	version.UpdateContent = postBody.UpdateContent
	version.ExtraInfo = postBody.ExtraInfo
	version.CreateTime = utils.GetCurrentTime()
	version.UpdateTime = utils.GetCurrentTime()

	o := orm.NewOrm()
	_, err = o.Delete(&version)
	if err != nil {
		resMap["extraMsg"] = "delete version " + version.VersionName + " error"
	} else {
		resMap["extraMsg"] = "delete version " + version.VersionName + " success"
		resMap["result"] = 1
	}

	this.Data["json"] = &resMap
	this.ServeJSON()
}

func (this *AddDeviceController) Post() {

	var postBody models.Device

	resMap := make(map[string]interface{})
	resMap["result"] = 0
	request := this.Ctx.Input.RequestBody

	err := json.Unmarshal(request, &postBody)
	if err != nil {
		resMap["error"] = &err
		resMap["extraMsg"] = "json Unmarshal failure"
		this.Data["json"] = &resMap
		this.ServeJSON()
		return
	}

	var device models.Device
	device.IsDebug = postBody.IsDebug
	device.DeviceNo = postBody.DeviceNo
	device.DeviceModel = postBody.DeviceModel
	device.DeviceBrand = postBody.DeviceBrand
	device.AndroidVersion = postBody.AndroidVersion
	device.Battery = postBody.Battery
	device.Memory = postBody.Memory
	device.StorageInside = postBody.StorageInside
	device.StorageOutside = postBody.StorageOutside
	device.AppVersion = postBody.AppVersion
	device.PublishTime = postBody.PublishTime
	device.Info = postBody.Info
	device.ExtraInfo = postBody.ExtraInfo
	device.IsRunning = postBody.IsRunning
	device.IsInputting = postBody.IsInputting

	o := orm.NewOrm()
	_, err = o.Insert(&device)
	if err != nil {
		resMap["error"] = &err
		resMap["extraMsg"] = "insert device " + device.DeviceNo + " error"
	} else {
		resMap["result"] = 1
	}

	this.Data["json"] = &resMap
	this.ServeJSON()
}

func (this *DeviceGetListController) Post() {
	var getDeviceBody PostGetDeviceBody
	resMap := make(map[string]interface{})
	resMap["result"] = 0
	request := this.Ctx.Input.RequestBody

	err := json.Unmarshal(request, &getDeviceBody)
	if err != nil {
		resMap["error"] = &err
		resMap["extraMsg"] = "DeviceGetListController json Unmarshal device " + getDeviceBody.DeviceNo + " error"
		this.Data["json"] = &resMap
		this.ServeJSON()
		return
	}

	var deviceList []models.Device
	o := orm.NewOrm()
	whereSql := " WHERE 1=1 "
	if getDeviceBody.DeviceNo != "" {
		whereSql += " AND device_no like '%" + getDeviceBody.DeviceNo + "'% "
	}
	if getDeviceBody.DeviceModel != "" {
		whereSql += " AND device_model like '%" + getDeviceBody.DeviceModel + "'% "
	}
	if getDeviceBody.DeviceBrand != "" {
		whereSql += " AND device_brand like '%" + getDeviceBody.DeviceBrand + "'% "
	}
	if getDeviceBody.AndroidVersion != "" {
		whereSql += " AND android_version like '%" + getDeviceBody.AndroidVersion + "'% "
	}
	if getDeviceBody.AppVersion != "" {
		whereSql += " AND app_version like '%" + getDeviceBody.AppVersion + "'% "
	}
	if getDeviceBody.StartTime != "" && getDeviceBody.EndTime != "" {
		whereSql += " AND publish_time BETWEEN " + getDeviceBody.StartTime + " AND " + getDeviceBody.EndTime
	}
	whereSql += " LIMIT " + strconv.Itoa(getDeviceBody.Limit) + " OFFSET " + strconv.Itoa(getDeviceBody.Page*getDeviceBody.Limit)

	sql := "SELECT * FROM device " + whereSql
	num, err := o.Raw(sql).QueryRows(&deviceList)
	if err != nil {
		resMap["error"] = &err
		resMap["extraMsg"] = "get device list failed"
		this.Data["json"] = &resMap
		this.ServeJSON()
		return
	}
	if num == 0 {
		resMap["extraMsg"] = "no data"
		resMap["result"] = 1
		this.Data["json"] = &resMap
		this.ServeJSON()
		return
	}

	resMap["result"] = 1
	resMap["data_list"] = &deviceList
	this.Data["json"] = &resMap
	this.ServeJSON()
}
